package aaa;

import java.lang.reflect.Method;
import org.neodatis.odb.Configuration;
import org.neodatis.odb.ODB;
import org.neodatis.odb.ODBFactory;
import org.neodatis.odb.ODBServer;
import org.softmed.neodatis.util.id.ClassFieldIDGenerators;
import org.softmed.neodatis.util.id.GenerateIDConfigurator;
import org.softmed.neodatis.util.id.GenerateIDTrigger;
import org.softmed.neodatis.util.id.generator.SequentialGenerator;
import org.softmed.neodatis.util.provider.ClientServerProvider;
import org.softmed.neodatis.util.provider.ClientServerProviderManager;
import org.softmed.neodatis.util.provider.ServerWrapper;
import org.softmed.neodatis.util.provider.EmbeddedProvider;
import org.softmed.neodatis.util.provider.ODBProvider;
import org.softmed.neodatis.util.reflection.ClassIDFieldRegistration;
import org.softmed.neodatis.util.trigger.TriggerEnvironment;

public class Main {

	/**
	 * @param args
	 * @throws Throwable
	 */
	public static void main(String[] args) throws Throwable {

		// test();
		String simpleDbName = "test.odb";
		String simpleProviderName = "basic";
		
		ServerWrapper defaultServer = new ServerWrapper();
		defaultServer.startupServer();
		ClientServerProviderManager.setDefaultServer(defaultServer);
		
		ServerWrapper server = ClientServerProviderManager.getDefaultServer();
		server.registerODB(simpleDbName,simpleProviderName);
		ClientServerProvider csProvider = new ClientServerProvider(server,
				simpleProviderName);

		GenerateIDConfigurator config = new GenerateIDConfigurator(
				csProvider);

		TriggerEnvironment tenv = new TriggerEnvironment();
		tenv.getInserts().add(config.getGenerateIDTrigger());
		server.registerTriggerEnvironments(simpleProviderName, tenv);




//		EmbeddedProvider basicProvider = new EmbeddedProvider(simpleDbName);
		// ODBProviderManager.registerProvider(simpleProviderName,
		// basicProvider);

//		String dbFileName = "client-server-test.odb";
//		String dbName = "client-server";
//		String csProviderName = "client-server-provider";
//		ServerWrapper csProvider = new ServerWrapper(8000,
//				dbFileName, dbName);

		// ODBProviderManager.registerProvider(csProviderName, csProvider);

		// change this to choose between client server or local mode
		// GenerateIDTrigger generateIDTrigger = new GenerateIDTrigger(
		// csProviderName);

//		GenerateIDConfigurator config = new GenerateIDConfigurator(csProvider);

		config.registerGenerator(Test.class, "id", new SequentialGenerator());
		config.registerGenerator(Test.class, "id2",
				new SequentialGenerator(500));

		config.registerGenerator(ChildB.class, "myOwnid",
				new SequentialGenerator());

		config.disableAllInheritedGeneratedFields(ChildC.class);
		config.registerGenerator(ChildC.class, "myOwnid",
				new SequentialGenerator());
		config.registerGenerator(ChildC.class, "id2", new SequentialGenerator(
				1000));

		config.registerGenerator(ChildCB.class, "sequence",
				new SequentialGenerator());

//		TriggerEnvironment tenv = new TriggerEnvironment();
//		tenv.getInserts().add(config.getGenerateIDTrigger());

//		basicProvider.setTriggerEnvironment(tenv);
//		csProvider.registerTriggerEnvironments(dbName, tenv);

		ODBProvider mainProvider = csProvider;
		// use this to replace existing generators
		// generateIDTrigger.replaceGenerator(Test.class, "id2",
		// new SequentialGenerator(500));

		// change this to choose between client server or local mode
		// ODBProviderManager manager = new ODBProviderManager(csProviderName);
		// ODBProviderManager manager = new
		// ODBProviderManager(simpleProviderName);

		// Create the instance to be stored
		Test test = new Test();
		test.setChildA(new ChildA());
		test.setChildCB(new ChildCB());
		// get an ODB
		ODB odb = mainProvider.getODB();

		// Store the object
		odb.store(test);

		// Close ODB
		odb.close();

		test.print();
		test.getChildA().print();
		test.getChildCB().print();

		// second test run - ChildA inherits the fields from Test
		// get an ODB
		odb = mainProvider.getODB();
		// Store the object
		ChildA childA = new ChildA();
		odb.store(childA);
		// Close ODB
		odb.close();
		childA.print();

		// third test run - ChildB inherits the fields from Test and adds
		// another one
		// get an ODB
		// generateIDTrigger.registerGenerator(ChildB.class, "myOwnid",
		// new SequentialGenerator());
		odb = mainProvider.getODB();
		// Store the object
		ChildB childB = new ChildB();
		odb.store(childB);
		// Close ODB
		odb.close();
		childB.print();

		// third test run - ChildC inherits the fields from Test, but disables
		// their use, instead adds a specific generated id one
//		 generateIDTrigger.disableInheritedGeneratedID(ChildC.class);
//		 generateIDTrigger.registerGenerator(ChildC.class, "myOwnid",
		// new SequentialGenerator());
		odb = mainProvider.getODB();
		// Store the object
		ChildC childC = new ChildC();
		odb.store(childC);
		// Close ODB
		odb.close();
		childC.print();
		// fourth test run - ChildCA inherits the fields from ChildC
		// only will get generic fields from ChildC, but not from Test
		odb = mainProvider.getODB();
		// Store the object
		ChildCA childCA = new ChildCA();
		odb.store(childCA);
		// Close ODB
		odb.close();
		childCA.print();

		// fifth test run - ChildCB inherits the fields from ChildC
		// only will get generic fields from ChildC, but not from Test
		// and adds a new one
		// generateIDTrigger.registerGenerator(ChildCB.class, "sequence",
		// new SequentialGenerator());
		odb = mainProvider.getODB();
		// Store the object
		ChildCB childCB = new ChildCB();
		odb.store(childCB);
		// Close ODB
		odb.close();
		childCB.print();

		// client-server example
		// ClientServerProvider.getTriggerEnvironments().put(dbName, tenv);

	}

	private static void test() throws Throwable {
		String dbFileName = "testing.odb";
		ODB odb = ODBFactory.open(dbFileName);
		// Create the instance to be stored
		Test test = new Test();
		test.setChildA(new ChildA());
		test.setChildCB(new ChildCB());

		odb.store(test);

		odb.close();
		System.exit(0);

	}

}
